package com.yc.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.yc.common.handler.MapResultHandler;
import com.yc.common.utils.AlyExcelUtil;
import com.yc.common.utils.Encrypt;
import com.yc.entity.User;
import com.yc.exception.CustomException;
import com.yc.mapper.MajorInfoMapper;
import com.yc.mapper.UserMapper;
import com.yc.vo.Result;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.yc.entity.ClassInfo;
import com.yc.mapper.ClassInfoMapper;
import com.yc.service.ClassInfoService;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;


/**
 * 班级表;(class_info)表服务实现类
 * @date : 2023-6-27
 */
@Service
public class ClassInfoServiceImpl implements ClassInfoService{
    @Resource
    private UserMapper userMapper;
    @Resource
    private ClassInfoMapper classInfoMapper;
    @Resource
    RedisTemplate redisTemplate;
    @Resource
    MajorInfoMapper majorInfoMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ClassInfo queryById(Integer id){
        return classInfoMapper.selectById(id);
    }

    /**
     * 分页查询
     *
     * @param classInfo 筛选条件
     * @param current   当前页码
     * @param size      每页大小
     * @return
     */
    @Override
    public Page<ClassInfo> paginQuery(ClassInfo classInfo, long current, long size, String major, String year) {

        //1. 构建动态查询条件
        LambdaQueryWrapper<ClassInfo> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(classInfo.getCname())) {
            queryWrapper.like(ClassInfo::getCname, classInfo.getCname());
        }
        if (StrUtil.isNotBlank(classInfo.getYearnumber())) {
            queryWrapper.like(ClassInfo::getYearnumber, classInfo.getYearnumber());
        }
        if (StrUtil.isNotBlank(classInfo.getCounselorName())) {
            queryWrapper.eq(ClassInfo::getCounselor, classInfo.getCounselorName().split(" ")[0]);
        }
        queryWrapper.eq(ClassInfo::getStatus,1);
        queryWrapper.orderByDesc(ClassInfo::getId);
        //2. 执行分页查询
        Page<ClassInfo> pagin = new Page<>(current, size, true);
        IPage<ClassInfo> selectResult = classInfoMapper.selectByPage(pagin, queryWrapper);
        pagin.setPages(selectResult.getPages());
        pagin.setTotal(selectResult.getTotal());
        pagin.setRecords(selectResult.getRecords());
        //3. 返回结果
        return pagin;
    }

    /**
     * 新增数据
     *
     * @param classInfo 实例对象
     * @return 实例对象
     */
    @Override
    public ClassInfo insert(ClassInfo classInfo){
        classInfoMapper.insert(classInfo);
        return classInfo;
    }


    /**
     * 下载批量添加学生的模板
     *
     * @param response
     * @return
     * @throws IOException
     */
    public Result<?> downloadTemplate(HttpServletResponse response) throws IOException {
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        org.springframework.core.io.Resource[] resources = resourcePatternResolver.
                getResources("classpath*:" + File.separator + "static" +
                        File.separator + "file" + File.separator + "template.xls");
        org.springframework.core.io.Resource resource = resources[0];
        InputStream inputStream = null;
        OutputStream out = null;
        try {
            //根据文件在服务器的路径读取该文件转化为流
            inputStream = resource.getInputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String time = simpleDateFormat.format(date);
            String fileName = "辅导员带班信息模板-" + time + ".xls";
            //设置文件ContentType类型，这样设置，会自动判断下载文件类型
            response.setContentType("multipart/form-data");
            //设置文件头：最后一个参数是设置下载文件名（设置编码格式防止下载的文件名乱码）
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + new String(fileName.getBytes("UTF-8"),
                            "ISO8859-1"));
            out = response.getOutputStream();
            int b = 0;
            while (b != -1) {
                b = inputStream.read(buffer);
                //写到输出流(out)中
                out.write(buffer, 0, b);
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(1, "下载失败");
        } finally {
            try {
                inputStream.close();
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 新增数据
     *
     * @param classInfos 实例对象
     * @return 实例对象
     */
    @Override
    public boolean insert(List<ClassInfo> classInfos) {
        if (classInfos == null) {
            return false;
        }
        try {
            classInfos.stream().forEach(classInfo -> {
                classInfoMapper.insert(classInfo);
            });
        } catch (Exception e) {
            throw new CustomException("-1", e.getMessage());
        }

        return true;
    }

    /**
     * 更新数据
     *
     * @param classInfo 实例对象
     * @return 实例对象
     */
    @Override
    public ClassInfo update(ClassInfo classInfo){
        //1. 根据条件动态更新
        LambdaUpdateChainWrapper<ClassInfo> chainWrapper = new LambdaUpdateChainWrapper<ClassInfo>(classInfoMapper);
        if(StrUtil.isNotBlank(classInfo.getCname())){
            chainWrapper.eq(ClassInfo::getCname, classInfo.getCname());
        }
        if(StrUtil.isNotBlank(classInfo.getYearnumber())){
            chainWrapper.eq(ClassInfo::getYearnumber, classInfo.getYearnumber());
        }
        //2. 设置主键，并更新
        chainWrapper.set(ClassInfo::getId, classInfo.getId());
        boolean ret = chainWrapper.update();
        //3. 更新成功了，查询最最对象返回
        if(ret){
            return queryById(classInfo.getId());
        }else{
            return classInfo;
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id){
        int total = classInfoMapper.deleteById(id);
        return total > 0;
    }

    /**
     * 查询是否有同样的班级名称
     *
     * @param cname 班级名称
     * @return 是否成功
     */
    @Override
    public int getClassInfoByCname(String cname) {
        int count = classInfoMapper.queryEqClass(cname);
        return count;
    }

    /**
     * 上传数据
     *
     * @param inputStream 数据流
     * @return 是否成功
     */
    @Override
    public int upload(InputStream inputStream) {
        //先判断是否先前有文件传输失败的情况而导致数据没有传输完毕的情况
        Object history = redisTemplate.opsForValue().get("Classline");
        int line = history == null ? 0 : (int) history;
        List<Map<String, Object>> maps = AlyExcelUtil.excelToShopIdList(inputStream).get(0);

        for (int i = line; i < maps.size(); i++, line++) {
            Map<String, Object> map = maps.get(i);
            String department = map.get("1").toString();
            if ("计算机科学与工程学院".equals(department)) {
                String[] contents = {map.get("1") + "", map.get("2") + "", map.get("3") + "", map.get("4") + ""};
                int reg = reg(line, contents);
                if (reg != 0) {
                    return reg;
                }

                String[] classes = contents[3].split("[, ]");
                List<ClassInfo> infos = new ArrayList<>();
                for (String clas : classes) {
                    String[] strings = clas.substring(1).split("]");
                    if (getClassInfoByCname(strings[1])!=0) {
                        continue;
                    }
                    ClassInfo info = new ClassInfo();
                    info.setCname(strings[1]);
                    info.setCounselor(Integer.parseInt(map.get("2") + ""));
                    info.setUdid(2);
                    info.setStatus(1);
                    info.setMajorid(majorInfoMapper.selectIdByMajor(strings[1].substring(0,2)));
                    info.setYearnumber("20"+strings[1].substring(2,4));
                    int i1 = 0;
                    for (i1 = 0; i1 < infos.size(); i1++) {
                        if(infos.get(i1).getCname().equals(strings[1]))
                            break;
                    }
                    if(i1==infos.size())
                        infos.add(info);
                }

                this.insert(infos);
                //加入辅导员的工号以及所带的班级
                User user = userMapper.selectAllByUsername(map.get("2") + "");
                if (user != null) {
                    continue;
                }
                user = new User();
                user.setUsername(map.get("2") + "");
                user.setNickname(map.get("3") + "");

                user.setUdid(1);
                user.setPassword(Encrypt.md5AndSha(map.get("2") + ""));
                ArrayList<Long> list = new ArrayList<>();
                list.add(2L);
                user.setRole(list);

                userMapper.insert(user);
            }
        }
        return 0;
    }

    /*
    验证上传表格的各个数据项
     */
    public int reg(int line, String[] content) {
        //先判断是否有不合规符号
        String regEx = "[_`~!@#$%^&*()+=|{}':;'.<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        for (String s : content) {
            Matcher m = p.matcher(s);
            if (m.find()) {
            /*传输的过程中出现特殊字符导致数据传输中断，但是改正过来之后再次传输还从首位数据录入信息就显得太慢了
            所以记录错误的位置然后等待下一次传输的时候就从错误的地方开始录入信息*/
                redisTemplate.opsForValue().set("Classline", line, 5, TimeUnit.MINUTES);
                return line + 3;
            }
        }
        return 0;
    }

    /**
     * 得到所有的专业以及年级信息
     * @return
     */
    @Override
    public Map<String, List<String>> getAllInfo(String teacherId) {
        //先查询登陆进来的工作人员的身份
        User user = userMapper.selectById(teacherId);
        List<String> classes = null;
        if(user.getRole().contains(3)){
            classes = classInfoMapper.selectClassInfo(teacherId);
        }else if(user.getRole().contains(2)){
            classes = classInfoMapper.selectClassInfo(teacherId);
        }else {
            classes = classInfoMapper.selectClassInfo(null);
        }

        Map<String, List<String>> listMap = new HashMap<>();
        List<String> majors = new ArrayList<>();
        List<String> years = new ArrayList<>();
        Set<String> demo1 = new HashSet<>();
        Set<String> demo2 = new HashSet<>();
        classes.forEach(clas -> {
            String year = clas.substring(clas.length() - 4, clas.length() - 2);
            String major = clas.substring(0, clas.length() - 4);
            demo1.add(major);
            demo2.add(year);
        });
        majors.addAll(demo1);
        years.addAll(demo2);
        listMap.put("majors", majors);
        listMap.put("years", years);
        return listMap;
    }

    @Override
    public ClassInfo selectByCname(String cname) {
        ClassInfo classInfo = classInfoMapper.selectByCname(cname);
        if (classInfo.getId() == null){
            throw new CustomException("0", "添加失败,该学生班级不存在,请联系管理员!");
        }else {
            return classInfo;
        }
    }

    /**
     * 查询所有的班级名
     * @return
     */
    @Override
    public Map<String, String> selectAllCname(String counselor) {
        MapResultHandler<String, String> mapResultHandler = new MapResultHandler<>();
        classInfoMapper.selectAllCname(mapResultHandler, counselor);
        return mapResultHandler.getMappedResults();
    }

    /**
     * 查入学年份
     * @return
     */
    public List<String> queryYearnumber(){
        List<String> list = classInfoMapper.queryYearnumber();
        return list;
    }

    /**
     *
     * @param classInfo 班级信息
     * @return
     */
    public int addClass(ClassInfo classInfo){
        return classInfoMapper.addClass(classInfo);
    }

    /**
     * 通过老师工号查询当前时间上课的班级
     * @param username 老师工号
     * @return 当前上课的班级
     */
    public List<ClassInfo> selectCnameByTeacherId(String username){
        List<ClassInfo> classInfos = classInfoMapper.selectCnameByTeacherId(username);
        if (classInfos.size() <= 0){
            throw new CustomException("0","暂无班级上课!");
        }
        return classInfos;
    }

    /**
     * 通过教师Id查询当前时间上课的班级
     * @param teacherId 教师Id
     * @return 当前上课的班级
     */
    public List<ClassInfo> selectClassByTeacherId(String teacherId){
        List<ClassInfo> classInfos = classInfoMapper.selectClassByTeacherId(teacherId);
        if (classInfos.size() <= 0){
            throw new CustomException("0", "暂无班级上课!");
        }
        return classInfos;
    }

    public List<Map<String,Object>> selectBanji(){
        List<Map<String, Object>> maps = classInfoMapper.selectBanji();
        return maps;
    }


}
